package lol.clann.minecraft.springboot.api.bukkit.rawmessage;

import relocate.com.fasterxml.jackson.databind.node.JsonNodeFactory;
import relocate.com.fasterxml.jackson.databind.node.ObjectNode;
import org.bukkit.ChatColor;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author pyz
 * @date 2018/8/18 上午11:02
 */
public class MessagePart implements Comparable<MessagePart> {

    public final List<ChatColor> styles = new ArrayList<>();
    public MessageEvent onClick;
    public MessageEvent onHover;
    public ChatColor color;
    public String text;

    public MessagePart(String text) {
        this.text = text == null ? "null" : text;
    }

    /**
     * Converts this {@link MessagePart} into a {@link ObjectNode}
     *
     * @return The Minecraft-compatible {@link ObjectNode}
     */
    public ObjectNode toJSON() {
        Objects.requireNonNull(text);

        ObjectNode obj = JsonNodeFactory.instance.objectNode();
        obj.put("text", text);

        if (color != null) {
            obj.put("color", color.name().toLowerCase());
        }

        for (ChatColor style : styles) {
            obj.put(RawMessage.stylesToNames.get(style), true);
        }

        if (onClick != null) {
            obj.put("clickEvent", onClick.toJSON());
        }

        if (onHover != null) {
            obj.put("hoverEvent", onHover.toJSON());
        }

        return obj;

    }

    /**
     * @return This {@link MessagePart} in legacy-style color/formatting codes
     */
    public String toLegacy() {
        StringBuilder output = new StringBuilder();
        if (color != null) {
            output.append(color.toString());
        }
        styles.stream()
                .map(ChatColor::toString)
                .forEach(output::append);

        return output.append(text).toString();
    }

    /**
     * @return The click event bound
     */
    public MessageEvent getOnClick() {
        return onClick;
    }

    /**
     * @param onClick The new click event to bind
     */
    public void setOnClick(MessageEvent onClick) {
        this.onClick = onClick;
    }

    /**
     * @return The hover event bound
     */
    public MessageEvent getOnHover() {
        return onHover;
    }

    /**
     * @param onHover The new hover event to bind
     */
    public void setOnHover(MessageEvent onHover) {
        this.onHover = onHover;
    }

    /**
     * @return The color
     */
    public ChatColor getColor() {
        return color;
    }

    /**
     * @param color The color to set
     */
    public void setColor(ChatColor color) {
        if (!color.isColor()) {
            throw new IllegalArgumentException(color.name() + " is not a color!");
        }
        this.color = color;
    }

    /**
     * @return The list of styles
     */
    public List<ChatColor> getStyles() {
        return styles;
    }

    /**
     * @param style The new style to add
     */
    public void addStyle(ChatColor style) {
        if (style == null) {
            throw new IllegalArgumentException("Style cannot be null!");
        }
        if (!style.isFormat()) {
            throw new IllegalArgumentException(color.name() + " is not a style!");
        }
        styles.add(style);
    }

    /**
     * @return The raw text
     */
    public String getText() {
        return text;
    }

    /**
     * @param text The raw text to set
     */
    public void setText(String text) {
        this.text = text;
    }


    @Override
    public int compareTo(@NotNull MessagePart o) {
        if (text == o.text) {
            return 0;
        }
        if (text == null) {
            return -1;
        }
        if (o.text == null) {
            return 1;
        }
        return text.compareTo(o.text);
    }

}
